-- LevelTileLoader.lua
-- 关卡切片加载器 - 修复版，使用协程处理异步加载

local LevelTileLoader = {}
LevelTileLoader.__index = LevelTileLoader

local Cache = require("Cache")
local LevelTileConfig = require("LevelTileConfig")

function LevelTileLoader.new()
    local instance = {
        loadedTiles = {},           -- 已加载的切片 {tileIndex = {node, sprite}}
        activeTiles = {},           -- 当前激活的切片
        loadingQueue = {},          -- 加载队列
        maxLoadingPerFrame = 1,     -- 每帧最大加载数量
        tileCache = {},             -- 切片纹理缓存
        isPreloading = false,
        sceneRoot = nil,            -- 场景根节点
        debugMode = false,
        _loadingThreads = {},       -- 加载协程
        _loadingInProgress = false
    }
    return setmetatable(instance, LevelTileLoader)
end

-- 设置场景根节点
function LevelTileLoader:setSceneRoot(sceneRoot)
    self.sceneRoot = sceneRoot
end

-- 预加载初始区域
function LevelTileLoader:preloadInitialArea(startRow, startCol)
    if self.isPreloading then return end
    
    self.isPreloading = true
    
    -- 加载起始切片及其周围切片
    local tilesToLoad = {}
    
    -- 起始切片
    table.insert(tilesToLoad, {row = startRow, col = startCol, priority = 0})
    
    -- 周围8个方向
    local neighbors = LevelTileConfig.getNeighbors(startRow, startCol)
    for _, neighbor in ipairs(neighbors) do
        table.insert(tilesToLoad, {row = neighbor.row, col = neighbor.col, priority = 1})
    end
    
    -- 按优先级排序
    table.sort(tilesToLoad, function(a, b)
        return a.priority < b.priority
    end)
    
    -- 加入加载队列
    for _, tile in ipairs(tilesToLoad) do
        self:addToLoadQueue(tile.row, tile.col, tile.priority)
    end
    
    return true
end

-- 添加到加载队列
function LevelTileLoader:addToLoadQueue(row, col, priority)
    local tileIndex = LevelTileConfig.getTileIndex(row, col)
    
    -- 检查是否已经加载或正在加载
    if self.loadedTiles[tileIndex] or self:isInLoadingQueue(tileIndex) then
        return false
    end
    
    table.insert(self.loadingQueue, {
        row = row,
        col = col,
        index = tileIndex,
        priority = priority or 0,
        filename = LevelTileConfig.tilePositions[tileIndex].filename
    })
    
    return true
end

-- 检查是否在加载队列中
function LevelTileLoader:isInLoadingQueue(tileIndex)
    for _, item in ipairs(self.loadingQueue) do
        if item.index == tileIndex then
            return true
        end
    end
    return false
end

-- 同步加载切片纹理
function LevelTileLoader:loadTileTextureSync(filename)
    -- 先检查缓存
    if self.tileCache[filename] then
        return self.tileCache[filename]
    end
    
    -- 使用Cache同步加载
    local success = Cache:load(filename)
    if not success then
        print("纹理加载失败: " .. filename)
        return nil
    end
    
    -- 创建纹理
    local Texture2D = require("Texture2D")
    local texture = Texture2D(filename)
    if texture then
        self.tileCache[filename] = texture
        return texture
    end
    
    return nil
end

-- 创建切片节点
function LevelTileLoader:createTileNode(row, col, texture)
    local tileInfo = LevelTileConfig.tilePositions[LevelTileConfig.getTileIndex(row, col)]
    if not tileInfo then return nil end
    
    local Sprite = require("Sprite")
    local Node = require("Node")
    local Vec2 = require("Vec2")
    
    -- 创建切片精灵
    local sprite = Sprite(texture)
    if not sprite then return nil end
    
    -- 设置精灵位置
    sprite.position = Vec2.zero
    
    -- 创建切片容器节点
    local tileNode = Node()
    tileNode.position = Vec2(tileInfo.worldX, tileInfo.worldY)
    
    -- 添加精灵到节点
    tileNode:addChild(sprite)
    
    -- 存储引用
    local tileData = {
        node = tileNode,
        sprite = sprite,
        row = row,
        col = col,
        index = tileInfo.index,
        position = tileInfo,
        isActive = true,
        isVisible = false
    }
    
    self.loadedTiles[tileInfo.index] = tileData
    
    return tileNode
end

-- 更新加载队列（每帧调用）- 同步版本
function LevelTileLoader:updateLoadQueue()
    if #self.loadingQueue == 0 then return 0 end
    
    local loadedThisFrame = 0
    
    -- 按优先级排序加载队列
    table.sort(self.loadingQueue, function(a, b)
        return a.priority < b.priority
    end)
    
    -- 处理加载队列
    for i = #self.loadingQueue, 1, -1 do
        if loadedThisFrame >= self.maxLoadingPerFrame then
            break
        end
        
        local tileInfo = self.loadingQueue[i]
        
        -- 同步加载纹理
        local texture = self:loadTileTextureSync(tileInfo.filename)
        
        if texture then
            -- 创建节点
            local tileNode = self:createTileNode(tileInfo.row, tileInfo.col, texture)
            
            if tileNode and self.sceneRoot then
                -- 添加到场景根节点
                self.sceneRoot:addChild(tileNode)
                self.loadedTiles[tileInfo.index].isVisible = true
            end
            
            loadedThisFrame = loadedThisFrame + 1
        end
        
        -- 从队列移除
        table.remove(self.loadingQueue, i)
    end
    
    return loadedThisFrame
end

-- 根据角色位置更新切片
function LevelTileLoader:updateByPlayerPosition(playerX, playerY)
    -- 获取角色所在的切片
    local currentRow, currentCol = LevelTileConfig.getTileByPosition(playerX, playerY)
    
    -- 计算3x3区域
    local minRow = math.max(1, currentRow - 1)
    local maxRow = math.min(LevelTileConfig.GRID_SIZE.rows, currentRow + 1)
    local minCol = math.max(1, currentCol - 1)
    local maxCol = math.min(LevelTileConfig.GRID_SIZE.cols, currentCol + 1)
    
    -- 激活3x3区域内的切片
    for row = minRow, maxRow do
        for col = minCol, maxCol do
            self:activateTile(row, col)
        end
    end
    
    -- 卸载不在激活区域的切片
    self:unloadInactiveTiles()
end

-- 激活切片
function LevelTileLoader:activateTile(row, col)
    local tileIndex = LevelTileConfig.getTileIndex(row, col)
    
    -- 标记为激活
    self.activeTiles[tileIndex] = true
    
    -- 如果已加载，确保可见
    if self.loadedTiles[tileIndex] then
        self.loadedTiles[tileIndex].isActive = true
        if self.loadedTiles[tileIndex].node then
            self.loadedTiles[tileIndex].node.visible = true
            self.loadedTiles[tileIndex].isVisible = true
        end
    else
        -- 添加到加载队列（高优先级）
        self:addToLoadQueue(row, col, 0)
    end
end

-- 卸载非激活切片
function LevelTileLoader:unloadInactiveTiles()
    local toUnload = {}
    
    for tileIndex, tileData in pairs(self.loadedTiles) do
        if not self.activeTiles[tileIndex] then
            table.insert(toUnload, tileIndex)
        end
    end
    
    for _, tileIndex in ipairs(toUnload) do
        self:unloadTile(tileIndex)
    end
    
    -- 清空激活标记
    self.activeTiles = {}
end

-- 卸载切片
function LevelTileLoader:unloadTile(tileIndex)
    local tileData = self.loadedTiles[tileIndex]
    if not tileData then return end
    
    -- 移除节点
    if tileData.node and tileData.node.parent then
        tileData.node:removeFromParent()
    end
    
    -- 从表中移除
    self.loadedTiles[tileIndex] = nil
end

-- 获取当前激活的切片节点
function LevelTileLoader:getActiveTileNodes()
    local nodes = {}
    for tileIndex, _ in pairs(self.activeTiles) do
        if self.loadedTiles[tileIndex] and self.loadedTiles[tileIndex].node then
            table.insert(nodes, self.loadedTiles[tileIndex].node)
        end
    end
    return nodes
end

-- 获取切片节点
function LevelTileLoader:getTileNode(row, col)
    local tileIndex = LevelTileConfig.getTileIndex(row, col)
    if self.loadedTiles[tileIndex] then
        return self.loadedTiles[tileIndex].node
    end
    return nil
end

-- 清理所有切片
function LevelTileLoader:cleanup()
    for tileIndex, tileData in pairs(self.loadedTiles) do
        if tileData.node and tileData.node.parent then
            tileData.node:removeFromParent()
        end
    end
    
    self.loadedTiles = {}
    self.activeTiles = {}
    self.loadingQueue = {}
    self.tileCache = {}
    self.isPreloading = false
    self.sceneRoot = nil
    
    return true
end

return LevelTileLoader